#include <asm/ptrace.h>
#include <asm/system.h>
+#ifdef XEN
+static inline int iosapic_irq_to_vector (int irq)
+{
+ return irq;
+}
+
+#undef irq_to_vector
+#define irq_to_vector(irq) iosapic_irq_to_vector(irq)
+#define AUTO_ASSIGN AUTO_ASSIGN_IRQ
+#endif
#undef DEBUG_INTERRUPT_ROUTING
register_percpu_irq (ia64_vector vec, struct irqaction *action)
{
irq_desc_t *desc;
+#ifndef XEN
unsigned int irq;
for (irq = 0; irq < NR_IRQS; ++irq)
desc->status |= IRQ_PER_CPU;
desc->handler = &irq_type_ia64_lsapic;
if (action)
-#ifdef XEN
- setup_vector(irq, action);
-#else
setup_irq(irq, action);
-#endif
}
+#else
+ desc = irq_descp(vec);
+ desc->status |= IRQ_PER_CPU;
+ desc->handler = &irq_type_ia64_lsapic;
+ if (action)
+ setup_vector(vec, action);
+#endif
}
#ifdef XEN
-int request_irq(unsigned int irq,
+int request_irq_vector(unsigned int vector,
void (*handler)(int, void *, struct cpu_user_regs *),
unsigned long irqflags, const char * devname, void *dev_id)
{
* otherwise we'll have trouble later trying to figure out
* which interrupt is which (messes up the interrupt freeing logic etc).
* */
- if (irq >= NR_IRQS)
+ if (vector >= NR_VECTORS)
return -EINVAL;
if (!handler)
return -EINVAL;
action->handler = handler;
action->name = devname;
action->dev_id = dev_id;
- setup_vector(irq, action);
+ setup_vector(vector, action);
if (retval)
xfree(action);
extern void ia64_slave_init_handler (void);
#ifdef XEN
extern void setup_vector (unsigned int vec, struct irqaction *action);
-#define setup_irq(irq, action) setup_vector(irq, action)
#endif
static ia64_mc_info_t ia64_mc_info;
if (cpe_vector >= 0) {
/* If platform supports CPEI, enable the irq. */
cpe_poll_enabled = 0;
+#ifndef XEN
for (irq = 0; irq < NR_IRQS; ++irq)
if (irq_to_vector(irq) == cpe_vector) {
desc = irq_descp(irq);
desc->status |= IRQ_PER_CPU;
- setup_irq(irq, &mca_cpe_irqaction);
+ setup_vector(irq, &mca_cpe_irqaction);
}
+#else
+ desc = irq_descp(cpe_vector);
+ desc->status |= IRQ_PER_CPU;
+ setup_vector(cpe_vector, &mca_cpe_irqaction);
+#endif
ia64_mca_register_cpev(cpe_vector);
IA64_MCA_DEBUG("%s: CPEI/P setup and enabled.\n", __FUNCTION__);
} else {
break;
irq_status_query.flags = 0;
/* Edge-triggered interrupts don't need an explicit unmask downcall. */
- if ( !strstr(irq_desc[irq_to_vector(irq)].handler->typename, "edge") )
+ if ( !strstr(irq_descp(irq)->handler->typename, "edge") )
irq_status_query.flags |= XENIRQSTAT_needs_eoi;
ret = copy_to_guest(arg, &irq_status_query, 1) ? -EFAULT : 0;
break;
* disabled.
*/
-int setup_vector(unsigned int irq, struct irqaction * new)
+int setup_vector(unsigned int vector, struct irqaction * new)
{
unsigned long flags;
struct irqaction *old, **p;
- irq_desc_t *desc = irq_descp(irq);
+ irq_desc_t *desc = irq_descp(vector);
/*
* The following block of code has to be executed atomically
desc->depth = 0;
desc->status &= ~(IRQ_DISABLED | IRQ_INPROGRESS | IRQ_GUEST);
- desc->handler->startup(irq);
- desc->handler->enable(irq);
+ desc->handler->startup(vector);
+ desc->handler->enable(vector);
spin_unlock_irqrestore(&desc->lock,flags);
return 0;
/* Vectors reserved by xen (and thus not sharable with domains). */
unsigned long ia64_xen_vector[BITS_TO_LONGS(NR_IRQS)];
-int setup_irq(unsigned int irq, struct irqaction * new)
+int setup_irq_vector(unsigned int vec, struct irqaction * new)
{
- unsigned int vec;
int res;
- /* Get vector for IRQ. */
- if (acpi_gsi_to_irq (irq, &vec) < 0)
+ if ( vec == IA64_INVALID_VECTOR )
return -ENOSYS;
/* Reserve the vector (and thus the irq). */
if (test_and_set_bit(vec, ia64_xen_vector))
return res;
}
-void free_irq(unsigned int irq)
+void release_irq_vector(unsigned int vec)
{
- unsigned int vec;
unsigned long flags;
irq_desc_t *desc;
- /* Get vector for IRQ. */
- if (acpi_gsi_to_irq(irq, &vec) < 0)
+ if ( vec == IA64_INVALID_VECTOR )
return;
desc = irq_descp(vec);
}
/* Never allocate the hypercall vector or Linux/BSD fast-trap vector. */
- vector_irq[HYPERCALL_VECTOR] = NEVER_ASSIGN;
- vector_irq[0x80] = NEVER_ASSIGN;
+ vector_irq[HYPERCALL_VECTOR] = NEVER_ASSIGN_IRQ;
+ vector_irq[0x80] = NEVER_ASSIGN_IRQ;
apic_intr_init();
static DEFINE_SPINLOCK(vector_lock);
int vector_irq[NR_VECTORS] __read_mostly = {
- [0 ... NR_VECTORS - 1] = FREE_TO_ASSIGN
+ [0 ... NR_VECTORS - 1] = FREE_TO_ASSIGN_IRQ
};
static void __do_IRQ_guest(int vector);
BUG_ON((vector > LAST_DYNAMIC_VECTOR) || (vector < FIRST_DYNAMIC_VECTOR));
spin_lock(&vector_lock);
- if ((irq = vector_irq[vector]) == AUTO_ASSIGN)
- vector_irq[vector] = FREE_TO_ASSIGN;
+ if ((irq = vector_irq[vector]) == AUTO_ASSIGN_IRQ)
+ vector_irq[vector] = FREE_TO_ASSIGN_IRQ;
spin_unlock(&vector_lock);
- return (irq == AUTO_ASSIGN) ? 0 : -EINVAL;
+ return (irq == AUTO_ASSIGN_IRQ) ? 0 : -EINVAL;
}
int assign_irq_vector(int irq)
spin_lock(&vector_lock);
- if ((irq != AUTO_ASSIGN) && (IO_APIC_VECTOR(irq) > 0)) {
+ if ((irq != AUTO_ASSIGN_IRQ) && (IO_APIC_VECTOR(irq) > 0)) {
spin_unlock(&vector_lock);
return IO_APIC_VECTOR(irq);
}
vector = current_vector;
- while (vector_irq[vector] != FREE_TO_ASSIGN) {
+ while (vector_irq[vector] != FREE_TO_ASSIGN_IRQ) {
vector += 8;
if (vector > LAST_DYNAMIC_VECTOR)
vector = FIRST_DYNAMIC_VECTOR + ((vector + 1) & 7);
current_vector = vector;
vector_irq[vector] = irq;
- if (irq != AUTO_ASSIGN)
+ if (irq != AUTO_ASSIGN_IRQ)
IO_APIC_VECTOR(irq) = vector;
spin_unlock(&vector_lock);
spin_unlock(&desc->lock);
}
-int request_irq(unsigned int irq,
+int request_irq_vector(unsigned int vector,
void (*handler)(int, void *, struct cpu_user_regs *),
unsigned long irqflags, const char * devname, void *dev_id)
{
* which interrupt is which (messes up the interrupt freeing
* logic etc).
*/
- if (irq >= NR_IRQS)
+ if (vector >= NR_VECTORS)
return -EINVAL;
if (!handler)
return -EINVAL;
action->name = devname;
action->dev_id = dev_id;
- retval = setup_irq(irq, action);
+ retval = setup_irq_vector(vector, action);
if (retval)
xfree(action);
return retval;
}
-void free_irq(unsigned int irq)
+void release_irq_vector(unsigned int vector)
{
- unsigned int vector = irq_to_vector(irq);
- irq_desc_t *desc = &irq_desc[vector];
+ irq_desc_t *desc = &irq_desc[vector];
unsigned long flags;
spin_lock_irqsave(&desc->lock,flags);
do { smp_mb(); } while ( desc->status & IRQ_INPROGRESS );
}
-int setup_irq(unsigned int irq, struct irqaction *new)
+int setup_irq_vector(unsigned int vector, struct irqaction *new)
{
- unsigned int vector = irq_to_vector(irq);
- irq_desc_t *desc = &irq_desc[vector];
+ irq_desc_t *desc = &irq_desc[vector];
unsigned long flags;
spin_lock_irqsave(&desc->lock,flags);
case MAP_PIRQ_TYPE_MSI:
vector = map->index;
if ( vector == -1 )
- vector = assign_irq_vector(AUTO_ASSIGN);
+ vector = assign_irq_vector(AUTO_ASSIGN_IRQ);
if ( vector < 0 || vector >= NR_VECTORS )
{
int i, irq;
for ( i = 0; i < ARRAY_SIZE(com); i++ )
if ( (irq = serial_irq(i)) >= 0 )
- free_irq(irq);
+ release_irq(irq);
}
void serial_resume(void)
{
int vector, ret;
- vector = assign_irq_vector(AUTO_ASSIGN);
+ vector = assign_irq_vector(AUTO_ASSIGN_IRQ);
if ( vector <= 0 )
{
gdprintk(XENLOG_ERR VTDPREFIX, "IOMMU: no vectors\n");
}
irq_desc[vector].handler = &iommu_msi_type;
- ret = request_irq(vector, amd_iommu_page_fault, 0, "amd_iommu", iommu);
+ ret = request_irq_vector(vector, amd_iommu_page_fault, 0,
+ "amd_iommu", iommu);
if ( ret )
{
irq_desc[vector].handler = &no_irq_type;
}
/* Make sure that vector is never re-used. */
- vector_irq[vector] = NEVER_ASSIGN;
+ vector_irq[vector] = NEVER_ASSIGN_IRQ;
vector_to_iommu[vector] = iommu;
iommu->vector = vector;
return vector;
#include "../vtd.h"
-int vector_irq[NR_VECTORS] __read_mostly = { [0 ... NR_VECTORS - 1] = -1};
+int vector_irq[NR_VECTORS] __read_mostly = {
+ [0 ... NR_VECTORS - 1] = FREE_TO_ASSIGN_IRQ
+};
/* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */
u8 irq_vector[NR_IRQS] __read_mostly;
{
int vector, ret;
- vector = assign_irq_vector(AUTO_ASSIGN);
+ vector = assign_irq_vector(AUTO_ASSIGN_IRQ);
if ( vector <= 0 )
{
gdprintk(XENLOG_ERR VTDPREFIX, "IOMMU: no vectors\n");
}
irq_desc[vector].handler = &dma_msi_type;
- ret = request_irq(vector, iommu_page_fault, 0, "dmar", iommu);
+ ret = request_irq_vector(vector, iommu_page_fault, 0, "dmar", iommu);
if ( ret )
{
irq_desc[vector].handler = &no_irq_type;
}
/* Make sure that vector is never re-used. */
- vector_irq[vector] = NEVER_ASSIGN;
+ vector_irq[vector] = NEVER_ASSIGN_IRQ;
vector_to_iommu[vector] = iommu;
return vector;
iounmap(iommu->reg);
free_intel_iommu(iommu->intel);
- free_irq(iommu->vector);
+ release_irq_vector(iommu->vector);
xfree(iommu);
drhd->iommu = NULL;
/* TODO */
}
-/* Special IRQ numbers */
-#define AUTO_ASSIGN (-1)
-#define NEVER_ASSIGN (-2)
-#define FREE_TO_ASSIGN (-3)
extern int assign_irq_vector (int irq);
#define hvm_pci_intx_link(dev, intx) \
(((dev) + (intx)) & 3)
-/* Extract the IA-64 vector that corresponds to IRQ. */
-static inline int
-irq_to_vector (int irq)
+#define IA64_INVALID_VECTOR ((unsigned int)((int)-1))
+static inline unsigned int irq_to_vector(int irq)
{
- return irq;
-}
+ int acpi_gsi_to_irq (u32 gsi, unsigned int *irq);
+ unsigned int vector;
+
+ if ( acpi_gsi_to_irq(irq, &vector) < 0)
+ return 0;
+ return vector;
+}
extern u8 irq_vector[NR_IRQS];
extern int vector_irq[NR_VECTORS];
};
extern irqreturn_t no_action(int cpl, void *dev_id, struct pt_regs *regs);
-extern int request_irq(unsigned int,
+extern int request_irq_vector(unsigned int,
irqreturn_t (*handler)(int, void *, struct pt_regs *),
unsigned long, const char *, void *);
-extern void free_irq(unsigned int, void *);
+extern void release_irq_vector(unsigned int, void *);
#endif
#define IA64_MAX_VECTORED_IRQ 255
#define IA64_NUM_VECTORS 256
-#define AUTO_ASSIGN -1
+#define AUTO_ASSIGN_IRQ (-1)
#define IA64_SPURIOUS_INT_VECTOR 0x0f
extern int vector_irq[NR_VECTORS];
extern u8 irq_vector[NR_IRQS];
-#define AUTO_ASSIGN -1
-#define NEVER_ASSIGN -2
-#define FREE_TO_ASSIGN -3
#define platform_legacy_irq(irq) ((irq) < 16)
#define IRQ_GUEST_EOI_PENDING 32 /* IRQ was disabled, pending a guest EOI */
#define IRQ_PER_CPU 256 /* IRQ is per CPU */
+/* Special IRQ numbers. */
+#define AUTO_ASSIGN_IRQ (-1)
+#define NEVER_ASSIGN_IRQ (-2)
+#define FREE_TO_ASSIGN_IRQ (-3)
+
/*
* Interrupt controller descriptor. This is all we need
* to describe about the low-level hardware.
extern irq_desc_t irq_desc[NR_VECTORS];
-extern int setup_irq(unsigned int, struct irqaction *);
-extern void free_irq(unsigned int);
-extern int request_irq(unsigned int irq,
+extern int setup_irq_vector(unsigned int, struct irqaction *);
+extern void release_irq_vector(unsigned int);
+extern int request_irq_vector(unsigned int vector,
void (*handler)(int, void *, struct cpu_user_regs *),
unsigned long irqflags, const char * devname, void *dev_id);
+#define setup_irq(irq, action) \
+ setup_irq_vector(irq_to_vector(irq), action)
+
+#define release_irq(irq) \
+ release_irq_vector(irq_to_vector(irq))
+
+#define request_irq(irq, handler, irqflags, devname, devid) \
+ request_irq_vector(irq_to_vector(irq), handler, irqflags, defname, devid)
+
extern hw_irq_controller no_irq_type;
extern void no_action(int cpl, void *dev_id, struct cpu_user_regs *regs);